﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Research.DynamicDataDisplay.DataSources.MultiDimensional;
using System.Windows.Media.Media3D;

namespace VectorFieldSampleApp
{
	/// <summary>
	/// Interaction logic for Window1.xaml
	/// </summary>
	public partial class Window1 : Window
	{
		public Window1()
		{
			InitializeComponent();
		}

		private const int width = 200;
		private const int height = 200;

		private void Window_Loaded(object sender, RoutedEventArgs e)
		{
			Vector[,] data =
				//CreateCheсkerboard();
				//DataSource2DHelper.CreateVectorData(width, height, (ix, iy) => new Vector(Math.Sin(((double)ix) / 30), Math.Cos(((double)iy) / 30)));
			//CreateCircleField();
			CreateCircleField2();
			//CreatePotentialField();


			double[] xs = Enumerable.Range(0, width).Select(i => (double)i).ToArray();
			double[] ys = Enumerable.Range(0, height).Select(i => (double)i).ToArray();

			var dataSource = new NonUniformDataSource2D<Vector>(xs, ys, data);
			DataContext = dataSource;
		}

		private static Vector[,] CreateCheсkerboard()
		{
			return DataSource2DHelper.CreateVectorData(width, height, (x, y) =>
			{
				var result = (x / 40) % 2 - (y / 40) % 2 == 0 ? new Vector(x + 1, 0) : new Vector(0, y + 1);
				return result;
			});
		}

		private static Vector[,] CreateCircleField()
		{
			return DataSource2DHelper.CreateVectorData(width, height, (x, y) =>
			{
				Vector result;

				double xc = x - width / 2;
				double yc = y - height / 2;
				if (xc != 0)
				{
					double beta = Math.Sqrt(1.0 / (1 + yc * yc / (xc * xc)));
					double alpha = -beta * yc / xc;
					result = new Vector(alpha, beta);
				}
				else
				{
					double alpha = Math.Sqrt(1.0 / (1 + xc * xc / (yc * yc)));
					double beta = -alpha * xc / yc;
					result = new Vector(alpha, beta);
				}

				if (Double.IsNaN(result.X))
				{
					result = new Vector(0, 0);
				}

				return result;
			});
		}

		public static Vector[,] CreateCircleField2()
		{
			return DataSource2DHelper.CreateVectorData(width, height, (x, y) =>
			{
				Vector3D center = new Vector3D(width / 2f, height / 2f, 0);
				Vector3D up = new Vector3D(0, 0, 1);
				Vector3D vec = center - new Vector3D(x, y, 0);
				Vector3D tangent = Vector3D.CrossProduct(vec, up);
				Vector value = new Vector(tangent.X, tangent.Y);
				//if (value.X != 0 || value.Y != 0)
				//    value.Normalize();

				return value;
			});
		}

		public static Vector[,] CreatePotentialField()
		{
			PotentialField field = new PotentialField();
			field.AddPotentialPoint(0, 0, 1);
			field.AddPotentialPoint(20, 30, -1);
			field.AddPotentialPoint(50, 100, 1);
			field.AddPotentialPoint(100, 200, 3);

			return DataSource2DHelper.CreateVectorData(width, height, (x, y) =>
			{
				return field.GetPotential(new Point(x, y));
			});
		}
	}
}
